#include "backtest/backtest_engine.h"
#include "utils/memory_manager.h"
#include <algorithm>
#include <cmath>
#include <stdexcept>
#include <iostream>

BacktestEngine::BacktestEngine()
    : initial_balance_(0.0)
    , current_balance_(0.0)
    , commission_rate_(0.0) {
    // 预分配内存
    trades_.reserve(1000000);
    daily_balance_.reserve(1000);
}

BacktestEngine::~BacktestEngine() {
    MemoryManager::checkLeaks();
}

void BacktestEngine::set_data_loader(std::shared_ptr<DataLoader> loader) {
    data_loader_ = loader;
}

void BacktestEngine::add_strategy(std::shared_ptr<StrategyBase> strategy) {
    strategy->set_signal_callback([this](const Signal& signal) {
        handle_signal(signal);
    });
    strategies_.push_back(strategy);
}

void BacktestEngine::set_initial_balance(double balance) {
    initial_balance_ = balance;
    current_balance_ = balance;
}

void BacktestEngine::set_commission_rate(double rate) {
    commission_rate_ = rate;
}

BacktestResult BacktestEngine::run(const std::string& symbol,
                                 const std::string& start_time,
                                 const std::string& end_time) {
    // 初始化回测结果
    BacktestResult result;
    result.start_balance = initial_balance_;
    
    // 记录开始时间
    auto start = std::chrono::high_resolution_clock::now();
    
    try {
        // 加载市场数据
        auto market_data = data_loader_->load_data(symbol, start_time, end_time);
        if (market_data.empty()) {
            throw std::runtime_error("No market data available for the specified period");
        }

        // 初始化策略
        for (auto& strategy : strategies_) {
            strategy->initialize();
        }

        // 按时间顺序处理每个市场数据
        for (const auto& data : market_data) {
            // 更新每日余额
            update_daily_balance(data.timestamp);

            // 向每个策略发送市场数据
            for (auto& strategy : strategies_) {
                strategy->on_market_data(data);
            }
        }

        // 结束策略
        for (auto& strategy : strategies_) {
            strategy->finalize();
        }

        // 计算回测指标
        result.end_balance = current_balance_ + calculate_unrealized_pnl();
        result.trades = trades_;
        calculate_metrics(result);

    } catch (const std::exception& e) {
        std::cerr << "Error during backtest: " << e.what() << std::endl;
        throw;
    }

    // 记录结束时间和执行时间
    auto end = std::chrono::high_resolution_clock::now();
    result.execution_time = end - start;

    // 打印内存使用报告
    MemoryManager::printMemoryUsage();

    return result;
}

void BacktestEngine::handle_signal(const Signal& signal) {
    // 根据信号创建订单
    Order order;
    order.symbol = signal.symbol;
    order.price = signal.price;
    order.quantity = signal.quantity;
    order.timestamp = signal.timestamp;
    
    switch (signal.type) {
        case SignalType::BUY:
            order.side = OrderSide::BUY;
            break;
        case SignalType::SELL:
            order.side = OrderSide::SELL;
            break;
        default:
            return; // HOLD信号不产生订单
    }
    
    // 处理订单
    handle_order(order);
}

void BacktestEngine::handle_order(const Order& order) {
    if (!can_execute_order(order)) {
        return;
    }

    // 创建成交记录
    Trade trade;
    trade.trade_id = "T" + std::to_string(trades_.size() + 1);
    trade.order_id = order.order_id;
    trade.symbol = order.symbol;
    trade.price = order.price;
    trade.quantity = order.quantity;
    trade.side = order.side;
    trade.timestamp = order.timestamp;
    trade.commission = calculate_commission(order.price, order.quantity);

    // 更新持仓
    update_position(trade);

    // 记录交易
    trades_.push_back(trade);
}

bool BacktestEngine::can_execute_order(const Order& order) {
    double required_funds = order.price * order.quantity;
    if (order.side == OrderSide::BUY) {
        required_funds += calculate_commission(order.price, order.quantity);
        return current_balance_ >= required_funds;
    }
    
    // 检查是否有足够的持仓可以卖出
    auto it = positions_.find(order.symbol);
    if (it == positions_.end() || it->second.quantity < order.quantity) {
        return false;
    }
    
    return true;
}

double BacktestEngine::calculate_commission(double price, double quantity) {
    return price * quantity * commission_rate_;
}

void BacktestEngine::update_position(const Trade& trade) {
    auto& position = positions_[trade.symbol];
    
    if (trade.side == OrderSide::BUY) {
        // 买入更新持仓
        double total_cost = position.quantity * position.avg_price;
        double new_cost = trade.quantity * trade.price;
        position.quantity += trade.quantity;
        position.avg_price = (total_cost + new_cost) / position.quantity;
        current_balance_ -= (trade.price * trade.quantity + trade.commission);
    } else {
        // 卖出更新持仓
        double realized_pnl = (trade.price - position.avg_price) * trade.quantity;
        position.realized_pnl += realized_pnl;
        position.quantity -= trade.quantity;
        current_balance_ += (trade.price * trade.quantity - trade.commission);
        
        if (position.quantity <= 0) {
            positions_.erase(trade.symbol);
        }
    }
}

void BacktestEngine::update_daily_balance(const std::string& timestamp) {
    // 提取日期部分（假设时间戳格式为：YYYY-MM-DD HH:mm:ss）
    std::string date = timestamp.substr(0, 10);
    daily_balance_[date] = current_balance_ + calculate_unrealized_pnl();
}

double BacktestEngine::calculate_unrealized_pnl() {
    double total_pnl = 0.0;
    for (const auto& [symbol, position] : positions_) {
        total_pnl += position.unrealized_pnl;
    }
    return total_pnl;
}

double BacktestEngine::calculate_realized_pnl() {
    double total_pnl = 0.0;
    for (const auto& [symbol, position] : positions_) {
        total_pnl += position.realized_pnl;
    }
    return total_pnl;
}

void BacktestEngine::calculate_metrics(BacktestResult& result) {
    // 计算交易统计
    result.total_trades = trades_.size();
    result.winning_trades = 0;
    result.losing_trades = 0;
    double total_profit = 0.0;
    double total_loss = 0.0;
    
    for (const auto& trade : trades_) {
        double pnl = 0.0;
        if (trade.side == OrderSide::SELL) {
            auto it = positions_.find(trade.symbol);
            if (it != positions_.end()) {
                pnl = (trade.price - it->second.avg_price) * trade.quantity - trade.commission;
            }
        }
        
        if (pnl > 0) {
            result.winning_trades++;
            total_profit += pnl;
            result.max_profit_trade = std::max(result.max_profit_trade, pnl);
        } else {
            result.losing_trades++;
            total_loss -= pnl;
            result.max_loss_trade = std::min(result.max_loss_trade, pnl);
        }
    }
    
    // 计算胜率
    result.win_rate = result.total_trades > 0 ? 
        static_cast<double>(result.winning_trades) / result.total_trades : 0.0;
    
    // 计算盈亏比
    result.profit_factor = total_loss > 0 ? total_profit / total_loss : 0.0;
    
    // 计算平均交易盈亏
    result.avg_profit_per_trade = result.winning_trades > 0 ? 
        total_profit / result.winning_trades : 0.0;
    result.avg_loss_per_trade = result.losing_trades > 0 ? 
        total_loss / result.losing_trades : 0.0;
    
    // 计算最大回撤
    result.max_drawdown = calculate_max_drawdown();
    
    // 计算夏普比率
    result.sharpe_ratio = calculate_sharpe_ratio();
}

double BacktestEngine::calculate_max_drawdown() {
    if (daily_balance_.empty()) {
        return 0.0;
    }
    
    double max_drawdown = 0.0;
    double peak = daily_balance_.begin()->second;
    
    for (const auto& [date, balance] : daily_balance_) {
        if (balance > peak) {
            peak = balance;
        }
        double drawdown = (peak - balance) / peak;
        max_drawdown = std::max(max_drawdown, drawdown);
    }
    
    return max_drawdown;
}

double BacktestEngine::calculate_sharpe_ratio() {
    if (daily_balance_.size() < 2) {
        return 0.0;
    }
    
    // 计算每日收益率
    std::vector<double> returns;
    auto it = daily_balance_.begin();
    double prev_balance = it->second;
    ++it;
    
    for (; it != daily_balance_.end(); ++it) {
        double daily_return = (it->second - prev_balance) / prev_balance;
        returns.push_back(daily_return);
        prev_balance = it->second;
    }
    
    // 计算平均收益率和标准差
    double sum = std::accumulate(returns.begin(), returns.end(), 0.0);
    double mean = sum / returns.size();
    
    double sq_sum = std::inner_product(returns.begin(), returns.end(), returns.begin(), 0.0);
    double std_dev = std::sqrt(sq_sum / returns.size() - mean * mean);
    
    // 假设无风险利率为0
    return std_dev > 0 ? (mean / std_dev) * std::sqrt(252) : 0.0; // 年化
}